package com.bckj.fastboot.flow.process.consumer;

import com.bckj.fastboot.core.util.ExecutionContext;
import com.bckj.fastboot.core.lang.exception.BusinessException;
import com.bckj.fastboot.core.extra.stage.BaseStageContext;
import com.bckj.fastboot.core.extra.stage.Stage;
import com.bckj.fastboot.core.extra.stage.StageException;
import com.bckj.fastboot.core.extra.stage.StageRepository;
import com.bckj.fastboot.flow.model.BpmnServiceTask;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
public class StageBpmnProcessConsumer implements BpmnProcessConsumer {

    private final StageRepository stageRepository;
    private final List<Stage<BaseStageContext>> successfulStages = new ArrayList<>();

    @Resource
    private Environment environment;

    @Override
    public void consume(ExecutionContext context, BpmnServiceTask serviceTask) {
        String delegateExpression = serviceTask.getDelegateExpression();
        if (delegateExpression != null && !delegateExpression.isBlank()) {
            //执行表达式
            log.debug("Execute expression: " + delegateExpression);
            // 模拟解析逻辑（实际需注入Environment）
            String stageId = PROPERTY_PLACEHOLDER_HELPER.replacePlaceholders(delegateExpression, placeholder -> {
                if (environment.containsProperty(placeholder)) {
                    return environment.getProperty(placeholder);
                }
                return placeholder;
            });
            Stage<BaseStageContext> stage = stageRepository.get(stageId);
            if (stage == null) {
                throw new BusinessException("stage is null, stageId=" + stageId);
            }
            try {
                stage.execute((BaseStageContext) context);
                successfulStages.add(stage);
            } catch (StageException e) {
                throw BusinessException.of(e);
            }
        }
    }

    @Override
    public void callback(ExecutionContext context) {
        for (int i = successfulStages.size() - 1; i >= 0; i--) {
            try {
                Stage<BaseStageContext> stage = successfulStages.get(i);
                stage.callback((BaseStageContext) context);
            } catch (Exception e) {
                log.error("执行流程回调异常", e);
            }
        }
    }

    @Override
    public void rollback(ExecutionContext context, Throwable error) {
        for (int i = successfulStages.size() - 1; i >= 0; i--) {
            try {
                Stage<BaseStageContext> stage = successfulStages.get(i);
                stage.callback((BaseStageContext) context);
            } catch (Exception e) {
                log.error("执行流程回滚异常", e);
            }
        }
    }
}
